#define _CRT_SECURE_NO_WARNINGS 1

//#include<iostream>
//using namespace std;
//
//void Test()
//{
//	int* p1 = (int*)malloc(sizeof(int));
//	free(p1);
//
//	// 1.malloc/calloc/realloc的区别是什么？
//	int* p2 = (int*)calloc(4, sizeof (int));
//	int* p3 = (int*)realloc(p2, sizeof(int)* 10);
//
//	// 这里需要free(p2)吗？
//	free(p3);
//}
//
//int main()
//{
//	Test();
//	return 0;
//}

//void Test()
//{
//	int* p1 = (int*)malloc(sizeof(int));
//
//	int* p2 = new int;
//	// 申请5个int的数组
//	int* p3 = new int[5];
//
//	// 申请1个int对象，初始化为5
//	int* p4 = new int(5);
//
//	//C++11支持new[] 用{}初始化  C++98不支持
//	int* p5 = new int[5]{1,2,3};
//
//	free(p1);
//
//	delete p2;
//	delete[] p3;
//	delete p4;
//	delete[] p5;
//
//	// 针对内置类型，new/delete跟malloc/free没有本质的区别，只有用法的区别
//	// new/delete 用法简化了
//}
//
//int main()
//{
//	Test();
//
//	return 0;
//}

//class A
//{
//public:
//	A(int a = 0)
//		: _a(a)
//	{
//		cout << "A():" << this << endl;
//	}
//
//	~A()
//	{
//		cout << "~A():" << this << endl;
//	}
//
//private:
//	int _a;
//};

//int main()
//{
//	// 1、堆上申请空间
//	A* p1 = (A*)malloc(sizeof(A));
//	if (p1 == NULL)
//	{
//		perror("malloc fail");
//		return 0;
//	}
//
//	// 1、释放空间
//	free(p1);
//
//	// 1、堆上申请空间  2、调用构造函数初始化
//	//A* p2 = new A;
//	A* p2 = new A(10);
//
//	// 1、调用析构函数清理对象中资源 2、释放空间
//	delete p2;
//
//	cout << endl << endl;
//
//	A* p3 = new A[2];
//	delete[] p3;
// 
//	/* C++11支持
//	 A* p3 = new A[2]{1,2};
//	 A* p3 = new A[2]{ A(1), A(2) };*/
//
//	// 结论：new/delete 是为自定义类型准备的。
//	// 不仅在对申请出来，还会调用构造和析构初始化和清理
//
//	return 0;
//}

//int main()
//{
//	// 失败返回NULL
//	char* p1 = (char*)malloc(1024u*1024u*1024u*2 - 1);
//	//cout << p1 << endl;
//	printf("%p\n", p1);
//
//	// new失败,不需要检查返回值，他失败是抛异常
//	try
//	{
//		char* p2 = new char[1024u * 1024u * 1024u * 2 - 1];
//		printf("%p\n", p2);
//		size_t n = 0;
//		/*while (1)
//		{
//		char* p2 = new char[1024];
//		++n;
//
//		printf("%p->[%d]\n", p2, n);
//		}*/
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//
//	return 0;
//}

//int main()
//{
//	// 失败返回NULL
//	char* p1 = (char*)malloc(1024u*1024u*1024u*2 - 1);
//	//cout << p1 << endl;
//	printf("%p\n", p1);
//
//	// new失败,不需要检查返回值，他失败是抛异常
//	try
//	{
//		//char* p2 = new char[1024u * 1024u * 1024u * 2 - 1];
//		char* p2 = (char*)operator new(1024u * 1024u * 1024u);
//		printf("%p\n", p2);
//		size_t n = 0;
//
//		operator delete(p2);
//		/*while (1)
//		{
//		char* p2 = new char[1024];
//		++n;
//
//		printf("%p->[%d]\n", p2, n);
//		}*/
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//
//	return 0;
//}
//

//#include<iostream>
//using namespace std;
//
//class A
//{
//public:
//	A(int a = 0)
//		: _a(a)
//	{
//		cout << "A():" << this << endl;
//	}
//
//	~A()
//	{
//		cout << "~A():" << this << endl;
//	}
//
//private:
//	int _a;
//};
//
//// 重载operator delete，在申请空间时：打印在哪个文件、哪个函数、第多少行，申请了多少个字节
//void* operator new(size_t size, const char* fileName, const char* funcName, size_t lineNo)
//{
//	void* p = ::operator new(size);
//	cout << "new:" /* << fileName << "||"*/ << funcName << "||"<< lineNo << "||" << p << "||" << size << endl;
//	return p;
//}
//
////// 重载operator delete，在释放空间时：打印再那个文件、哪个函数、第多少行释放，不实现这个，不然使用要加（）
////void operator delete(void* p, const char* fileName, const char* funcName, size_t lineNo)
////{
////	cout << "delete:" << fileName << "||" << funcName << "||" << lineNo << "||" << p << endl;
////	::operator delete(p);
////}
//
//// 重载operator delete
//void operator delete(void* p)
//{
//	cout << "delete:" << endl;
//	free(p);
//}
//
//#ifdef _DEBUG
//     #define new new(__FILE__, __FUNCTION__, __LINE__)
//     // #define delete(p) operator delete(p, __FILE__, __FUNCTION__, __LINE__) 不实现这个宏，不然使用要加（）
//#endif
//
//int main()
//{
//	A* p1 = new A;
//	delete p1;
//
//	A* p2 = new A[4];
//	delete[] p2;
//
//	A* p3 = new A;
//	delete p3;
//
//	A* p4 = new A;
//	delete p4;
//
//	A* p5 = new A;
//	delete p5;
//
//	return 0;
//}

// new -> operator new + 构造函数
// 默认情况下operator new使用全局库里面
// 每个类可以去实现自己专属operator new  new这个类对象，他就会调自己实现这个operator new

// 实现一个类专属的operator new  -- 了解一下

#include<iostream>
using namespace std;
//
class A
{
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A():" << this << endl;
	}

	~A()
	{
		cout << "~A():" << this << endl;
	}

private:
	int _a;
};
//
//struct ListNode
//{
//	int _val;
//	ListNode* _next;
//
//	static allocator<ListNode> alloc;// 内存池
//
//	void* operator new(size_t n)
//	{
//		cout << "operator new -> STL内存池allocator申请" << endl;
//		void* obj = alloc.allocate(1);
//		return obj;
//	}
//
//	void operator delete(void* ptr)
//	{
//		cout << "operator delete -> STL内存池allocator申请" << endl;
//
//		alloc.deallocate((ListNode*)ptr, 1);
//	}
//
//	struct ListNode(int val)
//		:_val(val)
//		, _next(nullptr)
//	{}
//};
//
//// allocator以后会讲，现在先了解即可
//allocator<ListNode> ListNode::alloc;
//
//int main()
//{
//	// 频繁申请ListNode. 想提高效率 -- 申请ListNode时，不去malloc，而是自己定制内存池
//	ListNode* node1 = new ListNode(1);
//	ListNode* node2 = new ListNode(2);
//	ListNode* node3 = new ListNode(3);
//
//	delete node1;
//	delete node2;
//	delete node3;
//
//	A* p1 = new A;
//
//	return 0;
//}

int main()
{
	A* p = new A[10];
		//申请一段内存，然后使用
	delete[] p;
	//释放，有什么问题？()
	return 0;
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//
//int globalVar = 1;
//static int staticGlobalVar = 1;
//void Test()
//{
//	static int staticVar = 1;
//	int localVar = 1;
//	int num1[10] = { 1, 2, 3, 4 };
//	char char2[] = "abcd";
//	const char* pChar3 = "abcd";
//	int* ptr1 = (int*)malloc(sizeof(int) * 4);
//	int* ptr2 = (int*)calloc(4, sizeof(int));
//	int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
//	free(ptr1);
//	free(ptr3);
//}
//1. 选择题：
//选项 : A.栈  B.堆  C.数据段(静态区)  D.代码段(常量区)
//globalVar在哪里？____   staticGlobalVar在哪里？____
//staticVar在哪里？____   localVar在哪里？____
//num1 在哪里？____
//
//char2在哪里？____ * char2在哪里？___
//pChar3在哪里？____ * pChar3在哪里？____
//ptr1在哪里？____ * ptr1在哪里？____
//2. 填空题：
//sizeof(num1) = ____;
//sizeof(char2) = ____;      strlen(char2) = ____;
//sizeof(pChar3) = ____;     strlen(pChar3) = ____;
//sizeof(ptr1) = ____;
//3. sizeof 和 strlen 区别？


//#include<iostream>
//using namespace std;
//
//class A
//{
//public:
//	A(int a = 0)
//		: _a(a)
//	{
//		cout << "A():" << this << endl;
//	}
//	~A()
//	{
//		cout << "~A():" << this << endl;
//	}
//private:
//	int _a;
//};
//
//int main()
//{
//	// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间
//	//还会调用构造函数和析构函数
//	A* p1 = (A*)malloc(sizeof(A));
//	A* p2 = new A(1);
//	free(p1);
//	delete p2;
//
//	// 内置类型是几乎是一样的
//	int* p3 = (int*)malloc(sizeof(int)); // C
//	int* p4 = new int;
//	free(p3);
//	delete p4;
//
//	A* p5 = (A*)malloc(sizeof(A) * 10);
//	A* p6 = new A[10];
//	free(p5);
//	delete[] p6;
//	return 0;
//}

///*
//operator new：该函数实际通过malloc来申请空间，当malloc申请空间成功时直接返回；申请空间
//失败，尝试执行:空间不足应对措施，如果该应对措施用户设置了，则继续申请，否则抛异常。
//*/
//void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
//{
//	// try to allocate size bytes
//	void* p;
//	while ((p = malloc(size)) == 0)
//		if (_callnewh(size) == 0)
//		{
//			// report no memory
//			// 如果申请内存失败了，这里会抛出bad_alloc 类型异常
//			static const std::bad_alloc nomem;
//			_RAISE(nomem);
//		}
//	return (p);
//}
///*
//operator delete: 该函数最终是通过free来释放空间的
//*/
//void operator delete(void* pUserData)
//{
//	_CrtMemBlockHeader* pHead;
//	RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
//	if (pUserData == NULL)
//		return;
//	_mlock(_HEAP_LOCK);  /* block other threads */
//	__TRY
//		        /* get a pointer to memory block header */
//		pHead = pHdr(pUserData);
//	         /* verify block type */
//	_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
//	_free_dbg(pUserData, pHead->nBlockUse);
//	__FINALLY
//		_munlock(_HEAP_LOCK);  /* release other threads */
//	__END_TRY_FINALLY
//		return;
//}
///*
//free的实现
//*/
//#define   free(p)               _free_dbg(p, _NORMAL_BLOCK)


//#include <stdio.h>
//#include <stdlib.h>
//
//struct ListNode 
//{
//	ListNode* _next;
//	ListNode* _prev;
//	int _val;
//};
//
//int main()
//{
//	struct ListNode* n1 = (struct ListNode*)malloc(sizeof(struct ListNode));
//	if (n1 == NULL)
//	{
//		printf("malloc failed!\n");
//		exit(-1);
//	}
//	n1->_next = NULL;
//	n1->_prev = NULL;
//	n1->_val = 0;
//
//	return 0;
//}

#include <iostream>
using namespace std;

class ListNode
{
public:
	ListNode(int val)
		: _next(nullptr)
		, _prev(nullptr)
		, _val(val)
	{}

private:
	ListNode* _next;
	ListNode* _prev;
	int _val;
};

int main()
{
	ListNode* n2 = new ListNode(0);

	return 0;
}